﻿
import flash.geom.Point;
import kliment.math.Calc;

/**
 * ...
 * @author	Kliment
 * @version	1.7.1
 */
class kliment.geom.Geom {
	static public var FULL_TUTN:Number = 360;
	static public var HALF_TUTN:Number = 180;
	static public var NORTH:Number = 0;
	static public var EAST:Number = 90;
	static public var SOUTH:Number = 180;
	static public var WEST:Number = 270;
	static public var halfPi:Number = 1.5707963267948966192313216916398;
	static public var _180divPi:Number = 57.295779513082320876798154814105;
	static public var _Pidiv180:Number = .017453292519943295769236907684886;
	
	static public function radToGrad(value:Number):Number {
		return value * _180divPi;
	}
	
	static public function gradToRad(value:Number):Number {
		return value * _Pidiv180;
	}
	
	static public function getNormalAngle(value:Number):Number {
		while (value > FULL_TUTN)
			value -= FULL_TUTN;
		
		while (value < -FULL_TUTN)
			value += FULL_TUTN;
		
		return value;
	}
	
	static public function pointmax(point1:Point, point2:Point):Point {
		var result:Point;
		var i:Number = arguments.length;
		while (--i) 
			result = _pointMax(arguments[i], arguments[i-1]);
		return result;
	}
	
	static private function _pointMax(point1:Point, point2:Point):Point{
		if (point1.length > point2.length)
			return point1;
		return point2;
	}
	
	static public function pointMin(point1:Point, point2:Point):Point {
		var result:Point;
		var i:Number = arguments.length;
		while (--i) 
			result = _pointMin(arguments[i], arguments[i-1]);
		return result;
	}
	
	static private function _pointMin(point1:Point, point2:Point):Point{
		if (point2.length < point1.length)
			return point2;
		return point1;
	}
	
	static public function pointTop(point1:Point, point2:Point):Point {
		var result:Point;
		var i:Number = arguments.length;
		while (--i) 
			result = _pointTop(arguments[i], arguments[i-1]);
		return result;
	}
	
	static private function _pointTop(point1:Point, point2:Point):Point{
		if (point2.y < point1.y)
			return point2;
		return point1;
	}
	
	static public function pointBottom(point1:Point, point2:Point):Point {
		var result:Point;
		var i:Number = arguments.length;
		while (--i) 
			result = _pointBottom(arguments[i], arguments[i-1]);
		return result;
	}
	
	static private function _pointBottom(point1:Point, point2:Point):Point{
		if (point2.y > point1.y)
			return point2;
		return point1;
	}
	
	static public function pointLeft(point1:Point, point2:Point):Point {
		var result:Point;
		var i:Number = arguments.length;
		while (--i) 
			result = _pointLeft(arguments[i], arguments[i-1]);
		return result;
	}
	
	static private function _pointLeft(point1:Point, point2:Point):Point{
		if (point2.x < point1.x)
			return point2;
		return point1;
	}
	
	static public function pointRight(point1:Point, point2:Point):Point {
		var result:Point;
		var i:Number = arguments.length;
		while (--i) 
			result = _pointRight(arguments[i], arguments[i-1]);
		return result;
	}
	
	static private function _pointRight(point1:Point, point2:Point):Point{
		if (point2.x > point1.x)
			return point2;
		return point1;
	}
	
	static public function rotatePoint(point:Point, center:Point, angle:Number):Point {
		angle = gradToRad(angle);
		var sin:Number = Math.sin(angle);
		var cos:Number  = Math.cos(angle);
		var result:Point = new Point(point.x - center.x, point.y - center.y);
		var x:Number  = center.x + (result.x * cos - result.y * sin);
		var y:Number  = center.y + (result.x * sin + result.y * cos);
		result.x = x;
		result.y = y;
		return result;
	}
	
	static public function rotatePoints(points:Array, center:Point, angle:Number):Array {
		for (var i in points)
			points[i] = rotatePoint(points[i], center, angle);
		return points;
	}
	
	static public function conerBbyAC(a:Number, c:Number):Number { 
		return Math.asin(a/c); 
	}
	
	static public function conerAbyBC(b:Number, c:Number):Number { 
		return Math.acos(b/c); 
	}
	
	static public function circleHitTest(center:Point, point:Point, radius:Number):Boolean {
		if (circleRadius(center, point) <= radius) 
			return true;
		return false;
	}
	
	static public function circleRadius(center:Point, point:Point):Number {
		return Math.sqrt(Calc.sqr(point.x - center.x) + Calc.sqr(point.y - center.y));
	}
	
	static public function circleLenght(radius:Number):Number {
		return 2 * Math.PI * radius;
	}
}